#ifndef ZHY_MUDUO_BASE_THREADPOOL_H
#define ZHY_MUDUO_BASE_THREADPOOL_H

#include "Condition.h"
#include "Mutex.h"
#include "Thread.h"

#include <functional>
#include <memory>
#include <vector>
#include <deque>

namespace _zhy_muduo
{
class ThreadPool
{
public:
	typedef std::function<void()> Task;
	explicit ThreadPool(const std::string &nameArg = std::string("ThreadPool"));
	~ThreadPool();

	//Must be called before start().
	void setMaxQueueSize(const int maxSize) { maxQueueSize_ = maxSize; }
	void setThreadInitCallback(const Task &cb){ threadInitCallback_ = cb; }

	void start(const int numThreads);
	void stop();

	const std::string& name() const
	{ return name_; }

	size_t queueSize() const;
	void run(const Task& f);
	void run(Task&& f);

private:
	bool isFull() const;
	void runInThread();
	Task take();

	mutable MutexLock mutex_;
	Condition notEmpty_;
	Condition notFull_;
	std::string name_;
	Task threadInitCallback_;
	std::vector<std::shared_ptr<_zhy_muduo::Thread>> threads_;
	std::deque<Task> queue_;
	size_t maxQueueSize_;
	bool running_;

	DISALLOW_COPY_AND_ASSIGN_11(ThreadPool);
};

}//namespace _zhy_muduo

#endif //ZHY_MUDUO_BASE_THREADPOOL_H